package tokencommon

import (
	"errors"
	"fmt"
	"time"

	"github.com/dgrijalva/jwt-go"

	lg "gitee.com/bm_guangge/bm_common/log"
)

var TokenKey []byte // = []byte("profession_key")

const (
	TOKEN_EXPIRES int = -20 // token 过期
	TOKEN_VALID   int = 0   // token 有效
)

type MyClaims struct {
	Data interface{} `json:"data,omitempty"`
	jwt.StandardClaims
}

func InitToken(tokenKey string) {
	TokenKey = make([]byte, 0)
	TokenKey = append(TokenKey, []byte(tokenKey)...)
}

// GenerateToken 生成Token
func GenerateToken(timeout int64, gd interface{}) (string, error) {
	dt := time.Now().Unix()
	dt += timeout

	claims := MyClaims{
		Data: gd,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: dt,
			Issuer:    "wuji_server",
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString(TokenKey)
}

// 验证token
func CheckToken(tokenString string) (int, interface{}, error) {

	token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}

		// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
		return TokenKey, nil
	})

	if token == nil {
		lg.ELogger.Println("令牌无效:", tokenString)
		return TOKEN_EXPIRES, nil, errors.New("令牌无效")
	}

	// gd := GenTokenData{}
	claims, ok := token.Claims.(*MyClaims)
	if ok && token.Valid {
		expiresat := claims.ExpiresAt

		lg.ILogger.Println("expiresat:", expiresat)
		dt := time.Now().Unix()
		if dt > expiresat {
			return TOKEN_EXPIRES, nil, errors.New("令牌过期")
		} else {

			return TOKEN_VALID, claims.Data, nil
		}
	} else {
		fmt.Println(err)
		return TOKEN_EXPIRES, nil, err
	}
}
